﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core;
using Cofe.Web.Interfaces;
using Cofe.Web.Utils;

namespace Cofe.Web.Implements
{
    [Export(typeof(ICofeService))]
    [ServicePriority(ServicePriorityAttribute.DefaultPriority_COFEWS)]
    public class HttpMessageFormatterManager : IHttpMessageFormatterManager
    {
        #region Constructor
        
        #endregion

        #region Methods

        public HttpResponseMessage CreateResponse(HttpRequestMessage request, object returnVal, ParameterDic pd,
            ResponseFormatterInfo info)
        {
            if (info.ETag != null)
            {                
                if (request.Headers.IfNoneMatch.Any(v => v.Tag == info.ETag))
                    return new HttpResponseMessage(HttpStatusCode.NotModified);
            }

            foreach (var f in ResponseFormatters)
                if (f.CanCreateResponse(request, returnVal, pd, info))
                {
                    var retVal = f.CreateResponse(request, returnVal, pd, info)
                                .SetMediaType(info.ResourceAttribute);

                    WebCacheMethod cacheMethod = WebCacheMethod.LastModified;

                    if (info.ETag != null)
                        retVal.Headers.ETag = new EntityTagHeaderValue(info.ETag);

                    if (info.ResourceAttribute != null)
                        cacheMethod = info.ResourceAttribute.CacheMethod;
                    
                    switch (cacheMethod)
                    {
                        case WebCacheMethod.None: return retVal;
                        case WebCacheMethod.LastModified: return retVal.SetLastModified(info.LastModified);
                        case WebCacheMethod.MaxAge: return retVal.SetMaxAge(info.MaxAge);
                        default: return retVal;
                    }   
                    //return retVal;
                }
            return new HttpResponseMessage(HttpStatusCode.NotImplemented);
        }

        public object CreateRequestObject(HttpRequestMessage request, Type type, ParameterDic parameters = null)
        {
            if (parameters == null)
                parameters = new ParameterDic();

            foreach (var f in RequestFormatters)
                if (f.CanCreateRequestObject(request, type, parameters))
                {
                    return f.CreateRequestObject(request, type, parameters);
                }

            return null;
        }
        
        #endregion

        #region Data

        IHttpResponseMessageFormatter[] _responseFormatters = null;
        IHttpRequestMessageFormatter[] _requestFormatters = null;
        
        #endregion

        #region Public Properties

        public IHttpResponseMessageFormatter[] ResponseFormatters { get { return _responseFormatters ?? (_responseFormatters = CofeServices.ServiceLocater.FindAllServices<IHttpResponseMessageFormatter>().ToArray()); } }
        public IHttpRequestMessageFormatter[] RequestFormatters { get { return _requestFormatters ?? (_requestFormatters = CofeServices.ServiceLocater.FindAllServices<IHttpRequestMessageFormatter>().ToArray()); } }
        
        #endregion




      
    }
}
